/*
 * Copyright (C) 2007, 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.takaharabooks.mhp3rd;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader.TileMode;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.text.Html;
import android.text.SpannableString;
import android.text.TextPaint;
import android.text.util.Linkify;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;


public class WeakPointGallery extends Activity implements Runnable 
{
	//**********************定数定義*************************
	// 背景用一マスのサイズ
	public final static int MISSION_NONE				= 0;
	public final static int MISSION_CORNER_ONE			= 1;
	public final static int MISSION_CORNER_TWO			= 2;
	public final static int MISSION_CORNER_THREE		= 3;
	public final static int MISSION_CORNER_FOUR			= 4;
	
	//public final static int TEXT_VIEW_ABC_TBL[] = {
	//	R.id.TextView00,
	//	R.id.TextView01,
	//	R.id.TextView02,
	//	R.id.TextView03,
	//	R.id.TextView04,
	//	R.id.TextView05,
	//	R.id.TextView06,
	//	R.id.TextView07
	//};
	
	//******************************************************

	  private int m_nMonsterID = -1;
	
	  private ImageAdapter m_csAdapter;
	  private ImageView m_selectedImageView;
	  private TextView  m_csDescriptionText;
	  private TextView  m_csNumberText;
	  //private TextView[]  m_csABCText;
	  //static private int m_nABCViewID = R.id.TextView00;
	  Bitmap m_selectedBitmap;
	  private String m_selectedImageName = "m_noimage";
	  // 絞り込み用
	  private Spinner m_csKindSpinner;
	  private Spinner m_csABCSpinner;
	  static private int m_nSelectedKind = 0;
	  static private int m_nSelectedABC = 0;
	  
	  // プログレスダイアログ
	  static private ProgressDialog waitDialog = null;
	    
	    // DB
	    DB_WeakPointGallery m_dbWeakPoint = null;
      
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.week_point);   
        
        // 画像ギャラリーから選択された画像を表示するイメージビュー
        m_selectedImageView = (ImageView) findViewById(R.id.selectedImageView);        
    	m_csDescriptionText = (TextView) findViewById(R.id.DescriptionText);
    	m_csNumberText = (TextView) findViewById(R.id.NumberText);

    	// もしまだ表示されていたら消去
    	dismissProgresDlg();
    	
        // 読み込み中のプログレスダイアログを表示
        waitDialog = new ProgressDialog(this);
        waitDialog.setTitle("Loading...");
        waitDialog.setMessage("データ読み込み中です。\nしばらくお待ちください...");
        waitDialog.setIndeterminate(false);
        waitDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        waitDialog.show();

        // 引数を取得
    	Bundle extras = getIntent().getExtras();
    	if (extras!=null) {
    		m_nMonsterID = (Integer)extras.getSerializable("ID");
    		m_nSelectedKind = 0;
    		m_nSelectedABC = 0;
    		m_nGalleryPosition = 0;
    	}
        
		// 処理開始
        Thread thread = new Thread(this);
        thread.start();
                
        // バックライトを点灯
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
   	}
    
    @Override
    public void onStart()
    {

        super.onStart();
    }
    
    @Override
    public void onPause()
    {
    	dismissProgresDlg();
    	super.onPause();
    }
    
    @Override
    public void onDestroy(){
    	if( null != m_dbWeakPoint ){
    		m_dbWeakPoint.CloseDB();    	
    	}
    	super.onDestroy();
    }
    
    @Override
    public Object onRetainNonConfigurationInstance() {
        // キャッシュする
    	final Integer nLoadedNum[] = new Integer[3];
    	nLoadedNum[0] = m_nSelectedKind;
    	nLoadedNum[1] = m_nSelectedABC;
    	nLoadedNum[2] = m_nGalleryPosition;
        return nLoadedNum; // これがgetLastNoneConfigurationInstance()の戻り値になる
    }
    
    // キャッシュの読み出し
    private void loadData() {
        final Object sData = getLastNonConfigurationInstance();
     
        // 初回時はネットから写真をロード
        if (sData == null) {
      		//m_nSelectedKind = 0;
      		//m_nSelectedABC = 0;
      		//m_nGalleryPosition = 0;
        } else {
        	Integer nLoadedNum[] = (Integer[])sData;
      		m_nSelectedKind = nLoadedNum[0];
      		m_nSelectedABC = nLoadedNum[1];
      		m_nGalleryPosition = nLoadedNum[2];
        }
    }
    
    @Override
	public void run()
    {
        // 時間のかかる処理をここに記述。    	
        // データベースを作成
    	if( null == m_dbWeakPoint ){
	        m_dbWeakPoint = new DB_WeakPointGallery(this); 
	        m_dbWeakPoint.InitDB();
			if( IsCallFromQuest() ){
	        	m_dbWeakPoint.SetDBFromQuest(m_nMonsterID);
			}else{
				m_dbWeakPoint.SetDB(m_nSelectedKind, m_nSelectedABC);
			}
    	}
    	
    	InitFileInfo();
    	InitAllImageCache();
        handler.sendEmptyMessage(0);
    }
    
    private Handler handler = new Handler()
    {
        @Override
		public void handleMessage(Message msg) {
            // 処理終了時の動作をここに記述。
        	
        	// 初期化
        	InitAllView();
    		
        	dismissProgresDlg();
    		
    		// アップデート時のメッセージを表示します
    		if(m_dbWeakPoint.m_bUpdateFlag){
    			ShowUpdateMessage();
    		}

    		// バックライトを消灯
    		getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        }
    };
    
    // 読み込み中ダイアログ削除
    private void dismissProgresDlg()
    {
		if(waitDialog != null && waitDialog.isShowing()){
			waitDialog.dismiss();
			waitDialog = null;
		}    	
    }
    
    // すべてのViewを初期化
    private void InitAllView()
    {
  		// 全種別を表示できるように初期化
    	loadData();
    	
        // ギャラリー初期
  		InitGallery();
  		
    	// 名前順に絞込みできるようにする
  		InitABCSpinner();
        
  		// モンスター種別に絞込みできるようにする
  		InitKindSpinner();
  		
  		//　以前のギャラリー位置にセット
  		SetSelectedGalleryPosition();

    	// 説明文を表示
		SetDescriptionText(m_selectedImageView, 0);
    }
    
    // 最初にイメージをキャッシュにセット
    public void InitAllImageCache()
    {
    	String strImageFileName = "";
    	int nIndexMax = m_dbWeakPoint.GetDataNum();
    	for(int nIndex=0; nIndex<nIndexMax; nIndex++){
    		//SDから取得した画像データをキャッシュに保持
    		strImageFileName = m_strFileDir + m_dbWeakPoint.GetImgName(nIndex) + ".jpg";    	
    		Bitmap image = BitmapFactory.decodeFile(strImageFileName, new BitmapFactory.Options());
            ImageCache.setImage(strImageFileName, image);
    	}
    }
    
    /*************************************
     * クエストから呼ばれたのかどうか
     **************************************/
    public boolean IsCallFromQuest()
    {
    	return (-1 < m_nMonsterID);
    }
    
    /*************************************
     * アップデート時の１回だけメッセージを表示
     **************************************/
    private void ShowUpdateMessage()
    {
    	String strMessage = String.format(
    			"【Ver.5.4.2】" + 
    			"\n" +
    			"\n" +
    			"①スライド動作の改善\n" + 
    			"②画像１枚追加\n" + 
    			"\n" +
    			"\n" +
    			"【追加画像一覧】\n" +
    			"■ナルガクルガ　１枚\n" +    			
    			"\n" +
    			"\n" +
    			"【画像取得について】\n" +
    			"イラストを表示する際にネット上から画像を取得します。\n" +
    			"一度ネットから画像を取得すれば、その後ネット上から取得しません。\n" +
    			"ＳＤカードがない場合は画像が表示されませんので、ご注意ください。\n" +
    			"\n" +
    			"【画像切替について】\n" +
    			"弱点早見表下部のモンスターの画像を長押しすることで画像を切替えられます。\n" +
    			"\n" +
    			"【追加画像について】\n" +
    			"手動での切り替えをお願いします。\n" +
    			"\n" +
    			"\n"
    	);
    	
    	//TextView csDlgTextView = new TextView(this);
    	//csDlgTextView.setAutoLinkMask(Linkify.WEB_URLS);
    	//csDlgTextView.setText(strHtml);
    	
    	new AlertDialog.Builder(this)
    	.setTitle("アップデート情報")
    	.setMessage(strMessage)
    	.setPositiveButton("OK", null)  
    	.show();  
    }
    
    /**
     * メニューを作成する
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        super.onCreateOptionsMenu(menu);

        // タイトルメニューの作成
        MenuItem csMenu1 = menu.add(Menu.NONE, Menu.FIRST, Menu.NONE, "タイトルへ");
        csMenu1.setIcon(android.R.drawable.ic_menu_revert);
        MenuItem csMenu2 = menu.add(Menu.NONE, Menu.FIRST+1, Menu.NONE, "画像一覧");
        csMenu2.setIcon(android.R.drawable.ic_menu_camera);
        MenuItem csMenu3 = menu.add(Menu.NONE, Menu.FIRST+2, Menu.NONE, "フルスクリーン");
        csMenu3.setIcon(android.R.drawable.ic_menu_view);
        MenuItem csMenu4 = menu.add(Menu.NONE, Menu.FIRST+3, Menu.NONE, "デフォルト画像に戻す");
        csMenu4.setIcon(android.R.drawable.ic_menu_rotate);
        MenuItem csMenu5 = menu.add(Menu.NONE, Menu.FIRST+4, Menu.NONE, "アップデート情報");
        csMenu5.setIcon(android.R.drawable.ic_menu_upload);
        
        return true;
    }
   /**
     * メニューボタン押下時の処理
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem menu)
    {
        switch (menu.getItemId()) {
        case Menu.FIRST:
            //Activity終了
            finish();
            return true;
        case Menu.FIRST+1:
            //画像一覧を表示
    		Intent intent = new Intent();
            intent.setClassName( "com.takaharabooks.mhp3rd",
            					 "com.takaharabooks.mhp3rd.MonsterGrid" );
            startActivity(intent);
            return true;
        case Menu.FIRST+2:
            //フルスクリーン処理
        	if(0 == (getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN)){
	        	getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
	        	menu.setTitle("通常の画面");
        	}else{
                //フルスクリーンなら元に戻す
	        	getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
	        	menu.setTitle("フルスクリーン");
        	}
            return true;
        case Menu.FIRST+3:
            //デフォルト画像に戻す－確認、YESなら
        	ConfirmDefaultAllImg();
            return true;
        case Menu.FIRST+4:
            //アップデート情報
        	ShowUpdateMessage();
            return true;
        default:
            break;
        }
        
        return super.onOptionsItemSelected(menu);
    }
    
    /*************************************
     * ギャラリーを作成しなおします
     **************************************/
    public void RemakeGallery(int nPos)
    {
    	InitGallery();
        SetItemSelect(nPos);    	
    }
        
    /*************************************
     * ギャラリーの初期化
     **************************************/
    static private int m_nGalleryPosition = 0;
    public void InitGallery()
    {
        // アダプタ
        m_csAdapter = new ImageAdapter(this);
    	
    	// Reference the Gallery view
        Gallery g = (Gallery) findViewById(R.id.gallery);
        g.setVisibility(View.VISIBLE);
        // Set the adapter to our custom adapter (below)
        g.setAdapter(new ImageAdapter(this));
        
        // 選択処理
        g.setOnItemSelectedListener( new OnItemSelectedListener() {
        	@Override
            public void onItemSelected(AdapterView parent, View v, int position, long id) {
        		m_nGalleryPosition = position;
        		SetItemSelect(position);
            }
        	@Override
        	public void onNothingSelected(AdapterView parent){
        	}
        });
        
        // 長押し処理
        g.setOnItemLongClickListener( new OnItemLongClickListener()
        {
        	@Override
            public boolean onItemLongClick(AdapterView<?> parent, View v, int position, long id)
        	{
        		m_nGalleryPosition = position;
        		ShowDialogForGallery();
        		
        		return false;
        	}
        });
        
        registerForContextMenu(g);
    }
    
    // 選択済みのギャラリーポジションにセット
    private void SetSelectedGalleryPosition(){
    	m_csKindSpinner.setSelection(m_nSelectedKind);
    	m_csABCSpinner.setSelection(m_nSelectedABC);
  		Gallery g = (Gallery) findViewById(R.id.gallery);
        g.setSelection(m_nGalleryPosition);    	
    }
    
    // ギャラリーを長押ししたときにでるダイアログ
    public void ShowDialogForGallery()
    {
		final CharSequence[] str_items = {"画像を変更", "素材を表示"};

		//builder.setTitle("");
		new AlertDialog.Builder(this)
        //.setIcon(R.drawable.icon)
        //.setTitle("Please Select Color")
        .setItems(str_items, new DialogInterface.OnClickListener(){
        	public void onClick(DialogInterface dialog, int which) {
		    	if(0 == which){
		    		IntentMonsterGrid(m_nGalleryPosition);
		    	}else{
		    		IntentMonsterMaterial(m_nGalleryPosition);
		    	}
        	}
        })
        .show();
    }

    // デフォルト画像に戻すかどうかの確認画面を表示
    private void ConfirmDefaultAllImg()
    {
    	new AlertDialog.Builder(this)
        .setTitle("デフォルト画像に戻す")
        .setMessage("すべてのイラストをデフォルトの状態に戻します\n\n変更したイラストもデフォルトの状態に戻りますが、\nよろしいですか？\n")
        .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                /* ここにYESの処理 */
            	m_dbWeakPoint.DefaultUserTbl();
            	m_dbWeakPoint.SetDB(0, 0);
            	// ギャラリー初期
            	InitAllView();
            }
        })
        .setNegativeButton("No", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {
                /* ここにNOの処理 */
            }
        })
        .show();
    }
    
    /*************************************
     * モンスター画像選択アクティビティを表示
     **************************************/
    public void IntentMonsterGrid(int nPosition)
    {
		Intent intent = new Intent();
        intent.setClassName(
               "com.takaharabooks.mhp3rd",
                "com.takaharabooks.mhp3rd.MonsterGrid");
        intent.putExtra("ID", (Integer)m_csAdapter.getWeakpointID(nPosition)+1);
        intent.putExtra("NAME", (String)m_csAdapter.getMonsterName(nPosition));
        intent.putExtra("LAND", getResources().getConfiguration().orientation);
        startActivityForResult(intent, nPosition);
    }
    
    /*************************************
     * モンスター画像選択アクティビティを表示
     **************************************/
    public void IntentMonsterMaterial(int nPosition)
    {
    	String strName = (String)m_csAdapter.getMonsterName(nPosition);
    	String[] strName2 = strName.split("\n");
    	String[] strName3 = strName2[0].split(" ");
    	String[] strName4 = strName3[0].split("　");
    	String[] strName5 = strName4[0].split("\\(");
    	
		Intent intent = new Intent();
        intent.setClassName(
               "com.takaharabooks.mhp3rd",
                "com.takaharabooks.mhp3rd.MonsterMaterialListActivity");
        intent.putExtra("NAME", strName5[0]);
        startActivityForResult(intent, nPosition);
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        //if (requestCode == SHOW_EDITOR) {
            if (resultCode > 0) {
            	Bundle extras = data.getExtras(); 
            	if (extras != null){
	            	int nLand = extras.getInt("LAND");
	            	if(nLand == getResources().getConfiguration().orientation){
	            		if( IsCallFromQuest() ){
	        	        	m_dbWeakPoint.SetDBFromQuest(m_nMonsterID);
	            		}else{
	            			m_dbWeakPoint.SetDB(m_nSelectedKind, m_nSelectedABC);
	            		}
	            		// ギャラリー初期
		            	RemakeGallery(requestCode);
		          		//　以前のギャラリー位置にセット
		          		SetSelectedGalleryPosition();
	            	}
            	}
          	}
        //}
    }
    
    /*************************************
     * モンスター種族絞込み機能の初期化
     **************************************/
    public void InitKindSpinner()
    {
  		m_csKindSpinner = (Spinner) findViewById(R.id.MonsterKindSpinner);
  		m_csKindSpinner.setSelection(0);
  		m_csKindSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
  		{  			
  			@Override
    		public void onItemSelected(AdapterView<?> parent, View view, int position, long id){
    			// データベースを作り変える
  				m_nSelectedKind = (int)id;
    	    	m_dbWeakPoint.SetDB(m_nSelectedKind, 0);
    	    	m_nSelectedABC = 0;
    	    	m_csABCSpinner.setSelection(0);
    	    	if(m_nSelectedKind==0){
    	    		m_csABCSpinner.setEnabled(true);
    	    	}else{
    	    		m_csABCSpinner.setEnabled(false);
    	    	}
    	    	// ギャラリーを作り直す
    	    	RemakeGallery(0);
    		}
  			
  			@Override
  			public void onNothingSelected(AdapterView<?> arg0) {
            }
    	});    	
  		
  		// 「全種類」以外なら無効
    	if(m_nSelectedKind==0){
    		m_csABCSpinner.setEnabled(true);
    	}else{
    		m_csABCSpinner.setEnabled(false);
    	}
  		// クエストから呼ばれたときは無効表示
        if( IsCallFromQuest() ){
        	m_csKindSpinner.setEnabled(false);
        }
    }
    
    /*************************************
     * モンスター名前絞込み機能の初期化
     **************************************/
    public void InitABCSpinner()
    {
  		m_csABCSpinner = (Spinner) findViewById(R.id.ABCSpinner);
  		m_csABCSpinner.setSelection(0);
  		m_csABCSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
  		{  			
  			@Override
    		public void onItemSelected(AdapterView<?> parent, View view, int position, long id){
    			// データベースを作り変える
    	    	int nNum = (int)id;
    	    	m_dbWeakPoint.SetDB(m_nSelectedKind, nNum);
    	    	m_nSelectedABC = nNum;
    	    	// ギャラリーを作り直す
    	    	RemakeGallery(0);
    		}
  			
  			@Override
  			public void onNothingSelected(AdapterView<?> arg0) {
            }
    	});

  		// クエストから呼ばれたときは無効表示
        if( IsCallFromQuest() ){
        	m_csABCSpinner.setEnabled(false);
        }
    }
    
    public void SetItemSelect(int position)
    {
        // 選択された画像をイメージビューに表示
        m_selectedImageName = (String) m_csAdapter.getItem(position);
    	//m_selectedBitmap = BitmapFactory.decodeResource( getResources(), m_selectedImageID );
        // モンスターイメージをセット
       	SetSelectedImageView();
    	// 説明文を表示
		SetDescriptionText(m_selectedImageView, position);
		// 数をセット
		String strNum = "" + (position+1) + "/" + m_csAdapter.getCount();
		m_csNumberText.setText(strNum);		
    }
    
	private String strTempImageName = "m_noimage";
    public void SetSelectedImageView()
    {
    	// 画像が変わるときだけ実行する
    	if(m_selectedImageName == strTempImageName){ return;}
    	else		{strTempImageName = m_selectedImageName;}
    	
        // ウィンドウサイズを取得
        WindowManager windowmanager = (WindowManager)getSystemService(WINDOW_SERVICE);
        Display disp = windowmanager.getDefaultDisplay();
        int nActivityWidth = disp.getWidth();
    	
        String strFilePath = getResources().getString(R.string.SD_DIR_PATH) + m_selectedImageName + ".jpg";
        m_selectedBitmap = BitmapFactory.decodeFile(strFilePath, new BitmapFactory.Options());
        if(null == m_selectedBitmap){
        	m_selectedBitmap = BitmapFactory.decodeResource( getResources(), R.drawable.m_noimage );
        }
    	ResizeBitmap(m_selectedBitmap, nActivityWidth, 0);
    	m_selectedBitmap = createReflect(m_selectedBitmap);  
    	m_selectedImageView.setImageBitmap(m_selectedBitmap);
		// イメージビューが押されたときの動作
		// 　クリック時は作者名を表示する
    	m_selectedImageView = (ImageView) findViewById(R.id.selectedImageView);
    	m_selectedImageView.setOnClickListener(new View.OnClickListener()
    	{
			@Override
			public void onClick(View v) {
				m_dbWeakPoint.SetWriterDB(m_selectedImageName);
				ShowImageViewDialog(m_dbWeakPoint.m_strMonsterWriterName[0],
									m_dbWeakPoint.m_strMonsterWriterUrl[0]);
			}
		});
    }

    /*************************************
     * ダイアログの表示
     **************************************/
    public void ShowImageViewDialog(String strName, String strURL)
    {
    	String strHtml = String.format("%s\n%s", strName, strURL);
    	
    	TextView csDlgTextView = new TextView(this);
    	csDlgTextView.setAutoLinkMask(Linkify.WEB_URLS);
    	csDlgTextView.setText(strHtml);
    	
    	new AlertDialog.Builder(this)
    	.setTitle("作者")
    	.setIcon(android.R.drawable.ic_menu_edit)
    	.setView(csDlgTextView)  
    	.setPositiveButton("OK", null)  
    	.show();  
    }
        
    // 長押し時の処理
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        //menu.add(R.string.str_weakpoint);
    }
    
    // アイテム選択時の処理
    @Override
    public boolean onContextItemSelected(MenuItem item) {
//        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
//        Toast.makeText(this, "Longpress: " + info.position, Toast.LENGTH_SHORT).show();
        return true;
    }

    /*************************************
     * 鏡像を作り出す
     **************************************/
    public static Bitmap createReflect (Bitmap originalImage){  
        final int reflectionGap = 4;  
  
        int width = originalImage.getWidth();  
        int height = originalImage.getHeight();  
  
        // y軸反転  
        Matrix matrix = new Matrix();  
        matrix.preScale(1, -1);  
           
        // y軸反転画像をオリジナル画像の半分の高さで生成  
        Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, height/2, width, height/2, matrix, false);  
        // オリジナル画像＋反転画像を書き込むBitmapを用意  
        Bitmap bitmapWithReflection = Bitmap.createBitmap(width  
        , (height + height/2), Config.ARGB_8888);  
  
        // bitmapに書き込むCanvas生成  
        Canvas canvas = new Canvas(bitmapWithReflection);  
        //　オリジナル画像をbitmapWithReflectionに書き込む  
        canvas.drawBitmap(originalImage, 0, 0, null);  
        Paint deafaultPaint = new Paint();  
        canvas.drawRect(0, height, width, height + reflectionGap, deafaultPaint);  
        canvas.drawBitmap(reflectionImage,0, height + reflectionGap, null);  
  
        Paint paint = new Paint();  
        LinearGradient shader = new LinearGradient(0, originalImage.getHeight(), 0,  
        bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff, 0x00ffffff,  
        TileMode.CLAMP);  
        paint.setShader(shader);  
        paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));  
        canvas.drawRect(0, height, width,  
        bitmapWithReflection.getHeight() + reflectionGap, paint);  
        return bitmapWithReflection;  
    }  
    
    /*************************************
     * ビットマップを指定の大きさにリサイズします
     * [I-O]csBmp:リサイズする画像
     * [IN.]nW：横幅
     * [IN.]nH:縦幅（０の場合、横幅の倍率に合わせてリサイズ）
     * return: リサイズした画像を返す
     **************************************/
    public Bitmap ResizeBitmap(Bitmap csBmp, int nW, int nH){
        int width = csBmp.getWidth();
        int height = csBmp.getHeight();
        int newWidth = nW;
        int newHeight = nH;

        // calculate the scale - in this case = 0.4f
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        if(newHeight == 0){
        	scaleHeight = scaleWidth;
        }

        // createa matrix for the manipulation
        Matrix matrix = new Matrix();
        // resize the bit map
        matrix.postScale(scaleWidth, scaleHeight);
        // rotate the Bitmap
        //matrix.postRotate(45);

        // recreate the new Bitmap
        Bitmap resizedBitmap = Bitmap.createBitmap(csBmp, 0, 0,
                          width, height, matrix, true);
        csBmp = resizedBitmap;

        return resizedBitmap;
    }
    
    public void SetMonsterNameText(String strKind, String strMonsterName)
    {
    	String strName = "【" + strKind + "】";
    	strName += strMonsterName;
    	CharSequence source = Html.fromHtml(strName);
    	
    	TextView strMonstarNameTextView = (TextView) findViewById(R.id.MonsterNameText);
    	strMonstarNameTextView.setText(source);
    	strMonstarNameTextView.setShadowLayer(2, 2, 2, Color.rgb(0x66, 0x66, 0x66));
    }
    
    /*************************************
     * 説明文をセット
     **************************************/
    public void SetDescriptionText(View csView, int nPosition)
    {
    	// モンスター名セット
    	SetMonsterNameText(	(String)m_csAdapter.getMonsterKindStr(nPosition), 
    						(String)m_csAdapter.getMonsterName(nPosition));
    	
    	// 説明文生成
    	String strDesc = "<font color=\"#ff0000\">\t火" + GetStarString(m_csAdapter.getMonsterWeakPointNum(nPosition, 0)) + "</font>\t";
    	strDesc += "　属性\t\t　罠・アイテム\t\t特殊\t\t 部位破壊\t 弱点部位<br>";
    	strDesc += "\t";
    	strDesc += "<font color=\"#0088ff\">水" + GetStarString(m_csAdapter.getMonsterWeakPointNum(nPosition, 1)) + "</font>\t";
    	strDesc += "<font color=\"#cc00cc\">毒" + GetStarString(m_csAdapter.getStatInt(nPosition, 0)) + "</font>\t";
    	strDesc += "<font color=\"#22aa44\">落とし穴" + GetMaruBatuString(m_csAdapter.getStatInt(nPosition, 4)) + "</font>\t";
    	strDesc += "<font color=\"#ffffff\">音類" + GetMaruBatuString(m_csAdapter.getStatInt(nPosition, 8)) + "</font>\t\t";
    	strDesc += "<font color=\"#ffffff\">咆哮" + GetBigSmallString(m_csAdapter.getStatInt(nPosition, 10)) + "</font>\t";
    	strDesc += m_csAdapter.getPartsStr(nPosition, 0) + "\t";
    	strDesc += "<font color=\'#00aaaa\'>[斬]</font>" + m_csAdapter.getArmyZanStr(nPosition) + "<br>";
    	strDesc += "\t";
    	strDesc += "<font color=\"#888800\">雷" + GetStarString(m_csAdapter.getMonsterWeakPointNum(nPosition, 2)) + "</font>\t";
    	strDesc += "<font color=\"#cccc00\">ﾏﾋ" + GetStarString(m_csAdapter.getStatInt(nPosition, 1)) + "</font>\t";
    	strDesc += "<font color=\"#cc00cc\">シビレ罠" + GetMaruBatuString(m_csAdapter.getStatInt(nPosition, 5)) + "</font>\t";
    	strDesc += "<font color=\"#0088ff\">肉類" + GetMaruBatuString(m_csAdapter.getStatInt(nPosition, 9)) + "</font>\t\t";
    	strDesc += "<font color=\"#ffffff\">風圧" + GetBigSmallString(m_csAdapter.getStatInt(nPosition, 11)) + "</font>\t";
    	strDesc += m_csAdapter.getPartsStr(nPosition, 1) + "\t";
    	strDesc += "<font color=\'#00aaaa\'>[打]</font>" + m_csAdapter.getArmyDaStr(nPosition) + "<br>";
    	strDesc += "\t";
    	strDesc += "<font color=\"#cccccc\">氷" + GetStarString(m_csAdapter.getMonsterWeakPointNum(nPosition, 3)) + "</font>\t";
    	strDesc += "<font color=\"#00ccff\">眠" + GetStarString(m_csAdapter.getStatInt(nPosition, 2)) + "</font>\t";
    	strDesc += "<font color=\"#cccc00\">　閃光玉" + GetMaruBatuString(m_csAdapter.getStatInt(nPosition, 6)) + "</font>\t";
    	strDesc += "\t\t\t";
    	strDesc += "\t\t\t\t";
    	strDesc += "" + m_csAdapter.getPartsStr(nPosition, 2) + "\t";
    	strDesc += "<font color=\'#00aaaa\'>[弾]</font>" + m_csAdapter.getArmyDanStr(nPosition) + "<br>";
    	strDesc += "\t";
    	strDesc += "<font color=\"#22aa44\">龍" + GetStarString(m_csAdapter.getMonsterWeakPointNum(nPosition, 4)) + "</font>\t";
    	strDesc += "<font color=\"#ffffff\">気" + GetStarString(m_csAdapter.getStatInt(nPosition, 3)) + "</font>\t";
    	strDesc += "<font color=\"#888800\">こやし玉" + GetMaruBatuString(m_csAdapter.getStatInt(nPosition, 7)) + "</font>\t";
    	strDesc += "\t\t\t";
    	strDesc += "\t\t\t\t" + m_csAdapter.getPartsStr(nPosition, 3) + "\t";
		
        // 色変更
        CharSequence source = Html.fromHtml(strDesc);
        
        // リサイズ
        SpannableString spannable = new SpannableString(source);
        //RelativeSizeSpan spanResize = new RelativeSizeSpan(1.1f); 
        //spannable.setSpan(spanResize, 0, 17, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);		
//        BackgroundColorSpan spanColor = new BackgroundColorSpan( 0xff0000 );
//        ForegroundColorSpan spanColor = new ForegroundColorSpan( 0xff0000 );
//        spannable.setSpan(spanColor, 34, 39, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
//      BlurMaskFilter filter = new BlurMaskFilter(1.0f, BlurMaskFilter.Blur.INNER);
//      MaskFilterSpan span = new MaskFilterSpan(filter);
//      SpannableString spannable = new SpannableString(strText);
//      spannable.setSpan(span, 0, spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    	
        // 表示
    	m_csDescriptionText.setVisibility(View.VISIBLE);
		m_csDescriptionText.setTextSize(14.0f);
    	m_csDescriptionText.setText(spannable);
//    	m_csDescriptionText.setText(strDesc);
    	m_csDescriptionText.setShadowLayer(2, 2, 2, Color.rgb(0x66, 0x66, 0x66));
    }
    
    /*************************************
     * 数値に対応した☆文字列を生成して取得
     **************************************/
    public String GetStarString(int nNum)
    {
    	String strStar = "";
    	for(int nStar=0; nStar<3; nStar++){
    		if(nStar < nNum){
    			strStar += "★";
    		}else{
    			strStar += "　";
    		}
    	}
    	return strStar;
    }
        
    /*************************************
     * 数値に対応した○×△文字列を生成して取得
     **************************************/
    public String GetMaruBatuString(int nNum)
    {
    	String strMaruBatu = "";
    	switch(nNum){
    	case 0:
    		strMaruBatu = "<B>×</B>";
    		break;
    	case 1:
    		strMaruBatu = "<B>△</B>";
    		break;
    	case 2:
    		strMaruBatu = "<B>○</B>";
    		break;    	
    	}
    	return strMaruBatu;
    }
    
    /*************************************
     * 数値に対応した○×△文字列を生成して取得
     **************************************/
    public String GetBigSmallString(int nNum)
    {
    	String strBigSmall = "";
    	switch(nNum){
    	case 0:
    		strBigSmall = "【－】";
    		break;
    	case 1:
    		strBigSmall = "【小】";
    		break;
    	case 2:
    		strBigSmall = "【大】";
    		break;    	
    	case 3:
    		strBigSmall = "【大+】";
    		break;    	
    	}
    	return strBigSmall;
    }
        
    // ＳＤファイル用変数
    private String m_strFileDir="";
    private String m_strFileName[];

    /*******************************************
     * イメージを保存
     *******************************************/
    public void InitFileInfo()
    {
		// 保存先の決定
		String strStatus = Environment.getExternalStorageState();
		File csInputFile;
		if (!strStatus.equals(Environment.MEDIA_MOUNTED)) {
			csInputFile = Environment.getDataDirectory();
		} else {
			csInputFile = new File(getResources().getString(R.string.SD_DIR_PATH));
			csInputFile.mkdirs();
		}
		m_strFileDir = csInputFile.getAbsolutePath() + "/";
		m_strFileName = csInputFile.list();
	}
    
    /*************************************
     * ImageAdapter（ギャラリーの画像処理を行う）
     **************************************/
    public class ImageAdapter extends BaseAdapter
    {
        int mGalleryItemBackground;

        public ImageAdapter(Context c) {
            mContext = c;

            // See res/values/attrs.xml for the <declare-styleable> that defines
            // Gallery1.
            TypedArray a = obtainStyledAttributes(R.styleable.MissionGallery);
            mGalleryItemBackground = a.getResourceId(
                    R.styleable.MissionGallery_android_galleryItemBackground, 0);
            a.recycle();
            
            InitFileInfo();
        }
        
        @Override
        public void finalize(){
        	ImageCache.clearCache();
        }
        
        /*******************************************
         * イメージを取得
         *******************************************/
        public Bitmap ReadImageFile(int nPosition)
        {
        	Bitmap readMapImage = null;
            try {
                readMapImage = BitmapFactory.decodeFile(m_strFileDir + m_strFileName[nPosition], new BitmapFactory.Options());
            } catch (Exception e) {
             	Toast.makeText(mContext, "ファイル読み込みエラー", Toast.LENGTH_SHORT);
            }
            return readMapImage;
        }
                
        /*************************************
         * マップイメージのファイル名を取得
         **************************************/
        public String getFileName(int position)
        {
        	return m_strFileName[position];
        }
        
        /*************************************
         * マップイメージのあるフォルダパスを取得
         **************************************/
        public String getFileDir()
        {
        	return m_strFileDir;
        }
        
        @Override
		public int getCount() {
            return m_dbWeakPoint.GetDataNum();
        }        
        
        @Override
		public Object getItem(int position) {
       		return m_dbWeakPoint.GetImgName(position);
        }
        
        /*************************************
         * テーブルＩＤ取得
         **************************************/
        public int getWeakpointID(int position){
        	return m_dbWeakPoint.GetWeakpointID(position);
        }

        /*************************************
         * モンスター名取得
         **************************************/
        public Object getMonsterName(int position) {
        	if(position < getCount()){
                return m_dbWeakPoint.GetMonsterName(position);
        	}else{
        		return "";
        	}
        }

        /*************************************
         * モンスター種別（文字列）取得
         **************************************/
        public Object getMonsterKindStr(int position) {
        	if(position < getCount()){
                return m_dbWeakPoint.GetMonsterKindStr(position);
        	}else{
        		return "";
        	}
        }

        /*************************************
         * モンスター種別（数値）取得
         **************************************/
        public Object getMonsterKindNum(int position) {
        	if(position < getCount()){
                return m_dbWeakPoint.GetMonsterKindNum(position);
        	}else{
        		return 0;
        	}
        }

        /*************************************
         * 弱点（文字列）取得
         **************************************/
        public Object getMonsterWeakPointStr(int position){
        	return m_dbWeakPoint.GetWeakPointStr(position);
        }
        
        /*************************************
         * 弱点（数値）取得
         **************************************/
        public int getMonsterWeakPointNum(int position, int nWPKind){
        	if(position < getCount()){
                return m_dbWeakPoint.GetMonsterWeakpointNum(position, nWPKind);
        	}else{
        		return 0;
        	}
        }

        /*************************************
         * 肉質（斬）（文字列）取得
         **************************************/
        public Object getArmyZanStr(int position){
        	return m_dbWeakPoint.GetArmyZanStr(position);
        }
        
        /*************************************
         * 肉質（打）（文字列）取得
         **************************************/
        public Object getArmyDaStr(int position){
        	return m_dbWeakPoint.GetArmyDaStr(position);
        }
        
        /*************************************
         * 肉質（弾）（文字列）取得
         **************************************/
        public Object getArmyDanStr(int position){
        	return m_dbWeakPoint.GetArmyDanStr(position);
        }

        /*************************************
         * 部位破壊（文字列）取得
         **************************************/
        public Object getPartsStr(int position, int nCol){
        	return m_dbWeakPoint.GetPartsStr(position, nCol);
        }
        
        /*************************************
         * 状態異常（数値）取得
         **************************************/
        public int getStatInt(int position, int nCol){
        	return m_dbWeakPoint.GetStatInt(position, nCol);
        }
        
        @Override
		public long getItemId(int position) {
            return position;
        }

        @Override
		public View getView(int position, View convertView, ViewGroup parent) {
            ImageView i;
            
            if (convertView == null) {
            	i = new ImageView(mContext);
	            String strItem = (String)getItem(position);
            	
	            // 画像があるものは表示
	            //if( "m_noimage" != strItem ){
	            //	i.setImageResource(strItem);
	            //}else{
	            //	i.setImageBitmap( getBitmapForGallery(nItem, position) );
	            //}
	            //i.setScaleType(ImageView.ScaleType.FIT_CENTER);
	            //i.setLayoutParams(new Gallery.LayoutParams(100, 100));
	            //画像読込
            	i.setImageBitmap( getBitmapForGallery(position) );
	            try{
	            	//String strImageName = DB_WeakPointGallery.m_strImageNumberMatchNames[position];
	                i.setTag(strItem);
	                // AsyncTaskは１回しか実行できない為、毎回インスタンスを生成
	                WeakPointImageGetTask task = new WeakPointImageGetTask((ImageView)i, strItem, mContext);
	                task.execute(m_strFileDir + strItem + ".jpg");
	            }
	            catch(Exception e){
	                //m_csProgbar.setVisibility(View.GONE);
	            }
	            //i.setScaleType(ImageView.ScaleType.FIT_CENTER);
                i.setVisibility(View.VISIBLE);
	            //i.setLayoutParams(new Gallery.LayoutParams(100, 100));
	
	            // The preferred Gallery item background
	            i.setBackgroundResource(mGalleryItemBackground);
            }else{
            	i = (ImageView)convertView;
            }

            return i;
        }
        
        /*************************************
         * ギャラリー用モンスター名（画像）の取得
         **************************************/
        public Bitmap getBitmapForGallery(int nPosition)
        {
        	Bitmap csBmp = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
        	Canvas csCanvas = new Canvas(csBmp);
        	
      		String strText = (String)getMonsterName(nPosition);
      		if(strText.length() > 0){
	    		TextPaint paintText = new TextPaint();
	            paintText.setTextSize(24);
	            paintText.setColor(Color.argb(255, 80, 80, 255));
	    		csCanvas.drawText(strText, 0, 3, 10, csBmp.getHeight()/3*1-10, paintText);
	    		csCanvas.drawText(strText, 3, 6, 15, csBmp.getHeight()/3*2-10, paintText);
	    		csCanvas.drawText(strText, 6, 9, 20, csBmp.getHeight()/3*3-10, paintText);
	    		//canvas.drawBitmap(reflectionImage,0, height + reflectionGap, null);
      		}        	
    		return csBmp;
        }
        
        /*************************************
         * 画像のセット
         **************************************/
        public void setImage(int nImgID, int nPosition)
        {
        	
        }

        private Context mContext;
        
    }

    /*************************************
     *************************************
     * ＳＤからよみこみ処理をするクラス
     **************************************
     **************************************/
    class WeakPointImageGetTask extends ImageGetTask
    {
    	// コンストラクタ
        public WeakPointImageGetTask(ImageView _image, String strImageFName, Context context ) {
            //対象の項目を保持しておく
        	super(_image, strImageFName, context);
        }
     
        @Override
        protected void onPostExecute(Bitmap result) {
            // Tagが同じものか確認して、同じであれば画像を設定する
            // （Tagの設定をしないと別の行に画像が表示されてしまう）
            if(tag.equals(image.getTag()))
            {
                if(result!=null){
                    //画像の設定
                	image.setImageBitmap(ResizeBitmap(result, 80, 80));
                    // モンスターイメージをセット
                	//if( m_strImageFName.equals(m_selectedImageName + ".jpg") ){
                	SetSelectedImageView();
                	//}
                }
                else{
                    //エラーの場合は×印を表示
                    //image.setImageDrawable(getResources().getDrawable(R.drawable.x));
                }
                //プログレスバーを隠し、取得した画像を表示
                image.setVisibility(View.VISIBLE);
            }
        }
    }  
    
}
